﻿using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.Prism.Regions;
using System.Collections.Specialized;
using System.Linq;

namespace UltimateNavigationFramework.UriNavigation
{
    public class UltimateNavigationFrameRegionBehavior : RegionBehavior
    {
        public const string BehaviorKey = "UltimateNavigationFrameRegionBehavior";
        
        private Boolean _isNavigating = false;
        private UltimateNavigationFrame _hostControl;

        /// <summary>
        /// Gets or sets the <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
        /// </summary>
        /// <value>A <see cref="DependencyObject"/> that the <see cref="IRegion"/> is attached to.
        /// This is usually a <see cref="FrameworkElement"/> that is part of the tree.</value>
        public UltimateNavigationFrame HostControl
        {
            get
            {
                return this._hostControl;
            }
            set
            {
                var newValue = value as UltimateNavigationFrame;
                if (newValue == null)
                {
                    throw new InvalidOperationException();
                }

                if (IsAttached)
                {
                    throw new InvalidOperationException();
                }

                this._hostControl = newValue;
            }
        }

        protected override void OnAttach()
        {
            if (this.HostControl == null)
            {
                throw new InvalidOperationException("No HostFrame defined in region.");
            }

            this._hostControl.Navigating += this.OnFrameNavigating;
            this._hostControl.NavigationFailed += this.OnFrameNavigationFailed;
            this._hostControl.NavigationStopped += this.OnFrameNavigationStopped;
            this._hostControl.Navigated += this.OnFrameNavigated;
            this.Region.ActiveViews.CollectionChanged += this.OnActiveViewsChanged;

            var regionName = this.HostControl.GetValue(RegionManager.RegionNameProperty) as string;
            if (!string.IsNullOrEmpty(regionName))
            {
                this.HostControl.Title = regionName;              
            }
        }

        private void OnFrameNavigating(Object sender, EventArgs e)
        {
            this._isNavigating = true;            
        }

        private void OnFrameNavigationFailed(Object sender, EventArgs e)
        {
            this._isNavigating = false;
        }

        private void OnFrameNavigationStopped(Object sender, EventArgs e)
        {
            this._isNavigating = false;
        }

        private void OnFrameNavigated(Object sender, EventArgs e)
        {
            this._isNavigating = false;
        }

        private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (!this._isNavigating)
            {
                var view = this.Region.ActiveViews.FirstOrDefault();
                this._hostControl.Content = view != null ? GetRegionContent(view) : null;
            }

            //var lastViewAdded = this.Region.ActiveViews.LastOrDefault();
            //if (lastViewAdded != null)
            //{
            //    this.HostControl.Content = lastViewAdded;
            //}
        }

        /// <summary>
        /// Creates the wrapper object should it not exist
        /// </summary>
        /// <param name="view"></param>
        /// <returns></returns>
        private DependencyObject GetRegionContent(Object view)
        {
            var frameworkElement = view as FrameworkElement;

            var titledPage = view as IPageTitle;

            var content =
                frameworkElement
                ?? new ContentControl
                {
                    Content = view,
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                    VerticalContentAlignment = VerticalAlignment.Stretch
                };

            if (content is UltimateNavigationFrameContent)
                return content;

            var contentWrapper =
                content.Parent
                ?? new UltimateNavigationFrameContent
                {
                    Content = content,
                    Title = titledPage != null ? titledPage.PageTitle : String.Empty
                };

            return contentWrapper;
        }
    }
}
